home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / asm-m68k / math-emu.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  6.6 KB  |  316 lines

  1. #ifndef _ASM_M68K_SETUP_H
  2. #define _ASM_M68K_SETUP_H
  3.  
  4. #include <asm/setup.h>
  5. #include <linux/linkage.h>
  6.  
  7. /* Status Register bits */
  8.  
  9. /* accrued exception bits */
  10. #define FPSR_AEXC_INEX    3
  11. #define FPSR_AEXC_DZ    4
  12. #define FPSR_AEXC_UNFL    5
  13. #define FPSR_AEXC_OVFL    6
  14. #define FPSR_AEXC_IOP    7
  15.  
  16. /* exception status bits */
  17. #define FPSR_EXC_INEX1    8
  18. #define FPSR_EXC_INEX2    9
  19. #define FPSR_EXC_DZ    10
  20. #define FPSR_EXC_UNFL    11
  21. #define FPSR_EXC_OVFL    12
  22. #define FPSR_EXC_OPERR    13
  23. #define FPSR_EXC_SNAN    14
  24. #define FPSR_EXC_BSUN    15
  25.  
  26. /* quotient byte, assumes big-endian, of course */
  27. #define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1))
  28.  
  29. /* condition code bits */
  30. #define FPSR_CC_NAN    24
  31. #define FPSR_CC_INF    25
  32. #define FPSR_CC_Z    26
  33. #define FPSR_CC_NEG    27
  34.  
  35.  
  36. /* Control register bits */
  37.  
  38. /* rounding mode */
  39. #define    FPCR_ROUND_RN    0        /* round to nearest/even */
  40. #define FPCR_ROUND_RZ    1        /* round to zero */
  41. #define FPCR_ROUND_RM    2        /* minus infinity */
  42. #define FPCR_ROUND_RP    3        /* plus infinity */
  43.  
  44. /* rounding precision */
  45. #define FPCR_PRECISION_X    0    /* long double */
  46. #define FPCR_PRECISION_S    1    /* double */
  47. #define FPCR_PRECISION_D    2    /* float */
  48.  
  49.  
  50. /* Flags to select the debugging output */
  51. #define PDECODE        0
  52. #define PEXECUTE    1
  53. #define PCONV        2
  54. #define PNORM        3
  55. #define PREGISTER    4
  56. #define PINSTR        5
  57. #define PUNIMPL        6
  58. #define PMOVEM        7
  59.  
  60. #define PMDECODE    (1<<PDECODE)
  61. #define PMEXECUTE    (1<<PEXECUTE)
  62. #define PMCONV        (1<<PCONV)
  63. #define PMNORM        (1<<PNORM)
  64. #define PMREGISTER    (1<<PREGISTER)
  65. #define PMINSTR        (1<<PINSTR)
  66. #define PMUNIMPL    (1<<PUNIMPL)
  67. #define PMMOVEM        (1<<PMOVEM)
  68.  
  69. #ifndef __ASSEMBLY__
  70.  
  71. #include <linux/kernel.h>
  72. #include <linux/sched.h>
  73.  
  74. union fp_mant64 {
  75.     unsigned long long m64;
  76.     unsigned long m32[2];
  77. };
  78.  
  79. union fp_mant128 {
  80.     unsigned long long m64[2];
  81.     unsigned long m32[4];
  82. };
  83.  
  84. /* internal representation of extended fp numbers */
  85. struct fp_ext {
  86.     unsigned char lowmant;
  87.     unsigned char sign;
  88.     unsigned short exp;
  89.     union fp_mant64 mant;
  90. };
  91.  
  92. /* C representation of FPU registers */
  93. /* NOTE: if you change this, you have to change the assembler offsets
  94.    below and the size in <asm/fpu.h>, too */
  95. struct fp_data {
  96.     struct fp_ext fpreg[8];
  97.     unsigned int fpcr;
  98.     unsigned int fpsr;
  99.     unsigned int fpiar;
  100.     unsigned short prec;
  101.     unsigned short rnd;
  102.     struct fp_ext temp[2];
  103. };
  104.  
  105. #ifdef FPU_EMU_DEBUG
  106. extern unsigned int fp_debugprint;
  107.  
  108. #define dprint(bit, fmt, args...) ({            \
  109.     if (fp_debugprint & (1 << (bit)))        \
  110.         printk(fmt, ## args);            \
  111. })
  112. #else
  113. #define dprint(bit, fmt, args...)
  114. #endif
  115.  
  116. #define uprint(str) ({                    \
  117.     static int __count = 3;                \
  118.                             \
  119.     if (__count > 0) {                \
  120.         printk("You just hit an unimplemented "    \
  121.                "fpu instruction (%s)\n", str);    \
  122.         printk("Please report this to ....\n");    \
  123.         __count--;                \
  124.     }                        \
  125. })
  126.  
  127. #define FPDATA        ((struct fp_data *)current->thread.fp)
  128.  
  129. #else    /* __ASSEMBLY__ */
  130.  
  131. #define FPDATA        %a2
  132.  
  133. /* offsets from the base register to the floating point data in the task struct */
  134. #define FPD_FPREG    (TASK_THREAD+THREAD_FPREG+0)
  135. #define FPD_FPCR    (TASK_THREAD+THREAD_FPREG+96)
  136. #define FPD_FPSR    (TASK_THREAD+THREAD_FPREG+100)
  137. #define FPD_FPIAR    (TASK_THREAD+THREAD_FPREG+104)
  138. #define FPD_PREC    (TASK_THREAD+THREAD_FPREG+108)
  139. #define FPD_RND        (TASK_THREAD+THREAD_FPREG+110)
  140. #define FPD_TEMPFP1    (TASK_THREAD+THREAD_FPREG+112)
  141. #define FPD_TEMPFP2    (TASK_THREAD+THREAD_FPREG+124)
  142. #define FPD_SIZEOF    (TASK_THREAD+THREAD_FPREG+136)
  143.  
  144. /* offsets on the stack to access saved registers,
  145.  * these are only used during instruction decoding
  146.  * where we always know how deep we're on the stack.
  147.  */
  148. #define FPS_DO        (PT_D0)
  149. #define FPS_D1        (PT_D1)
  150. #define FPS_D2        (PT_D2)
  151. #define FPS_A0        (PT_A0)
  152. #define FPS_A1        (PT_A1)
  153. #define FPS_A2        (PT_A2)
  154. #define FPS_SR        (PT_SR)
  155. #define FPS_PC        (PT_PC)
  156. #define FPS_EA        (PT_PC+6)
  157. #define FPS_PC2        (PT_PC+10)
  158.  
  159. .macro    fp_get_fp_reg
  160.     lea    (FPD_FPREG,FPDATA,%d0.w*4),%a0
  161.     lea    (%a0,%d0.w*8),%a0
  162. .endm
  163.  
  164. /* Macros used to get/put the current program counter.
  165.  * 020/030 use a different stack frame then 040/060, for the
  166.  * 040/060 the return pc points already to the next location,
  167.  * so this only needs to be modified for jump instructions.
  168.  */
  169. .macro    fp_get_pc dest
  170.     move.l    (FPS_PC+4,%sp),\dest
  171. .endm
  172.  
  173. .macro    fp_put_pc src,jump=0
  174.     move.l    \src,(FPS_PC+4,%sp)
  175. .endm
  176.  
  177. .macro    fp_get_instr_data    f,s,dest,label
  178.     getuser    \f,%sp@(FPS_PC+4)@(0),\dest,\label,%sp@(FPS_PC+4)
  179.     addq.l    #\s,%sp@(FPS_PC+4)
  180. .endm
  181.  
  182. .macro    fp_get_instr_word    dest,label,addr
  183.     fp_get_instr_data    w,2,\dest,\label,\addr
  184. .endm
  185.  
  186. .macro    fp_get_instr_long    dest,label,addr
  187.     fp_get_instr_data    l,4,\dest,\label,\addr
  188. .endm
  189.  
  190. /* These macros are used to read from/write to user space
  191.  * on error we jump to the fixup section, load the fault
  192.  * address into %a0 and jump to the exit.
  193.  * (derived from <asm/uaccess.h>)
  194.  */
  195. .macro    getuser    size,src,dest,label,addr
  196. |    printf    ,"[\size<%08x]",1,\addr
  197. .Lu1\@:    moves\size    \src,\dest
  198.  
  199.     .section .fixup,"ax"
  200.     .even
  201. .Lu2\@:    move.l    \addr,%a0
  202.     jra    \label
  203.     .previous
  204.  
  205.     .section __ex_table,"a"
  206.     .align    4
  207.     .long    .Lu1\@,.Lu2\@
  208.     .previous
  209. .endm
  210.  
  211. .macro    putuser    size,src,dest,label,addr
  212. |    printf    ,"[\size>%08x]",1,\addr
  213. .Lu1\@:    moves\size    \src,\dest
  214. .Lu2\@:
  215.  
  216.     .section .fixup,"ax"
  217.     .even
  218. .Lu3\@:    move.l    \addr,%a0
  219.     jra    \label
  220.     .previous
  221.  
  222.     .section __ex_table,"a"
  223.     .align    4
  224.     .long    .Lu1\@,.Lu3\@
  225.     .long    .Lu2\@,.Lu3\@
  226.     .previous
  227. .endm
  228.  
  229. /* work around binutils idiocy */
  230. old_gas=-1
  231. .irp    gas_ident.x .x
  232. old_gas=old_gas+1
  233. .endr
  234. .if !old_gas
  235. .irp    m b,w,l
  236. .macro    getuser.\m src,dest,label,addr
  237.     getuser .\m,\src,\dest,\label,\addr
  238. .endm
  239. .macro    putuser.\m src,dest,label,addr
  240.     putuser .\m,\src,\dest,\label,\addr
  241. .endm
  242. .endr
  243. .endif
  244.  
  245. .macro    movestack    nr,arg1,arg2,arg3,arg4,arg5
  246.     .if    \nr
  247.     movestack    (\nr-1),\arg2,\arg3,\arg4,\arg5
  248.     move.l    \arg1,-(%sp)
  249.     .endif
  250. .endm
  251.  
  252. .macro    printf    bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5
  253. #ifdef FPU_EMU_DEBUG
  254.     .data
  255. .Lpdata\@:
  256.     .string    "\string"
  257.     .previous
  258.  
  259.     movem.l    %d0/%d1/%a0/%a1,-(%sp)
  260.     .if    \bit+1
  261. #if 0
  262.     moveq    #\bit,%d0
  263.     andw    #7,%d0
  264.     btst    %d0,fp_debugprint+((31-\bit)/8)
  265. #else
  266.     btst    #\bit,fp_debugprint+((31-\bit)/8)
  267. #endif
  268.     jeq    .Lpskip\@
  269.     .endif
  270.     movestack    \nr,\arg1,\arg2,\arg3,\arg4,\arg5
  271.     pea    .Lpdata\@
  272.     jsr    printk
  273.     lea    ((\nr+1)*4,%sp),%sp
  274. .Lpskip\@:
  275.     movem.l    (%sp)+,%d0/%d1/%a0/%a1
  276. #endif
  277. .endm
  278.  
  279. .macro    printx    bit,fp
  280. #ifdef FPU_EMU_DEBUG
  281.     movem.l    %d0/%a0,-(%sp)
  282.     lea    \fp,%a0
  283. #if 0
  284.     moveq    #'+',%d0
  285.     tst.w    (%a0)
  286.     jeq    .Lx1\@
  287.     moveq    #'-',%d0
  288. .Lx1\@:    printf    \bit," %c",1,%d0
  289.     move.l    (4,%a0),%d0
  290.     bclr    #31,%d0
  291.     jne    .Lx2\@
  292.     printf    \bit,"0."
  293.     jra    .Lx3\@
  294. .Lx2\@:    printf    \bit,"1."
  295. .Lx3\@:    printf    \bit,"%08x%08x",2,%d0,%a0@(8)
  296.     move.w    (2,%a0),%d0
  297.     ext.l    %d0
  298.     printf    \bit,"E%04x",1,%d0
  299. #else
  300.     printf    \bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8)
  301. #endif
  302.     movem.l    (%sp)+,%d0/%a0
  303. #endif
  304. .endm
  305.  
  306. .macro    debug    instr,args
  307. #ifdef FPU_EMU_DEBUG
  308.     \instr    \args
  309. #endif
  310. .endm
  311.  
  312.  
  313. #endif    /* __ASSEMBLY__ */
  314.  
  315. #endif    /* _ASM_M68K_SETUP_H */
  316.